using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;

namespace Tool
{
    public class SoundFile
    {
        string m_FileName;
        string m_FileType;
        string m_FilePath;
        int m_Frequency;
        int m_BitDepth;
        int m_Channels;

        // T0 CHANGE:
        int m_Length; //length in miliseconds

        bool m_streaming;

        Editor m_parent;

        public SoundFile(string filename, Editor parent)
        {
            m_parent = parent;
            m_FileName = filename;
            m_FilePath = filename;

            m_FileName = ParseFilename();
            string name = m_FileName.Remove(m_FileName.Length - 4);

            string pathOnly = filename.Remove( filename.Length - m_FileName.Length );
            System.IO.Directory.SetCurrentDirectory( pathOnly );

            unsafe
            {
                uint soundHandle = parent.GetToolSystemInterface().NewSoundFile((sbyte*)System.Runtime.InteropServices.Marshal.StringToHGlobalAnsi(name).ToPointer(),
                                       (sbyte*)System.Runtime.InteropServices.Marshal.StringToHGlobalAnsi(m_FileName).ToPointer());
                m_FileType = ".WAV";
                m_Frequency = (int)parent.GetToolSystemInterface().GetSoundFreq(&soundHandle);
                m_BitDepth = (int)parent.GetToolSystemInterface().GetSoundBitDepth(&soundHandle);
                m_Channels = (int)parent.GetToolSystemInterface().GetSoundChannels(&soundHandle);

                //Random rand = new Random();
                m_Length = parent.GetToolSystemInterface().GetSoundLength(&soundHandle);//*/1000;// +rand.Next(5000);// "00:01:23";

                m_streaming = false;
            }
        }

        public string ParseFilename()
        {
            // decrement by one, to account for zero-based indexing
            int len = m_FilePath.Length - 1;
            
            // get the last character in the string
            char walkString = m_FilePath[len];

            string reverseName = null;
            
            // while the current index isn't equal to '\'
            while (walkString.CompareTo('\\') != 0 && len >= 0)
            {
                // copy the character to what will be our reversed-string
                reverseName += walkString.ToString();

                // decrement the index into the path
                --len;

                // make sure not to index into crazy memory...
                if (len >= 0)
                {
                    // then get the next char
                    walkString = m_FilePath[len];
                }
            }

            string finalString = null;
            int finalIndex = reverseName.Length - 1;

            while (finalIndex >= 0 )
            {
                // get the reversed-strings last character, the file name's first character
                finalString += reverseName[finalIndex].ToString();
                finalIndex--;
            }

            return finalString;
        }

        public string GetFileName()
        {
            return m_FileName;
        }

        public string GetFilePath()
        {
            return m_FilePath;
        }

        public string GetFileType()
        {
            return m_FileType;
        }

        public int GetNumChannels()
        {
            return m_Channels;
        }

        public int GetFileLength()
        {
            return m_Length;
        }

        public int GetFileFrequency()
        {
            return m_Frequency;
        }

        public int GetBitDepth()
        {
            return m_BitDepth;
        }

        public bool GetStreaming()
        {
            return m_streaming;
        }

        public void SetStreaming(bool streaming, int soundIndex)
        {
            m_parent.SoundBankGrid.Rows[soundIndex].Cells[6].Value = streaming;

            m_streaming = streaming;
        }
    }


    public class SoundLibrary
    {
        private System.Windows.Forms.Form m_EditorParent;           // for access to dropdowns
        private System.Windows.Forms.DataGridView m_GridParent;     // for access to the soundbank grid

        public ArrayList m_FileList = new ArrayList();
        public int m_Size;

        public SoundLibrary(System.Windows.Forms.Form editorParent, System.Windows.Forms.DataGridView gridParent)
        {
            m_EditorParent = editorParent;
            m_GridParent = gridParent;
        }

        public void AddFile(SoundFile newSoundFile)
        {
            if (newSoundFile != null)
            { 
                m_FileList.Add(newSoundFile);
                ((Editor)m_EditorParent).AddSoundDropDown.Items.Add(newSoundFile.GetFileName());

                m_GridParent.Rows.Add(1);

                m_GridParent.Rows[m_Size].Cells["Filename"].Value = newSoundFile.GetFileName();
                m_GridParent.Rows[m_Size].Cells["FileType"].Value = newSoundFile.GetFileType();
                m_GridParent.Rows[m_Size].Cells["Length"].Value = String.Format("{0:N2} s", newSoundFile.GetFileLength() / 1000.0f);
                m_GridParent.Rows[m_Size].Cells["Frequency"].Value = string.Concat(newSoundFile.GetFileFrequency(), " Hz");
                m_GridParent.Rows[m_Size].Cells["BitsPerSample"].Value = string.Concat(newSoundFile.GetBitDepth(), "-bit");
                m_GridParent.Rows[m_Size].Cells["Channels"].Value = newSoundFile.GetNumChannels();
                m_GridParent.Rows[m_Size].Cells["Streaming"].Value = false;

                m_Size += 1;
            }
        }

        public void DeleteFile()
        {
            // get the index, so we can read in the file name
            //int index = m_GridParent.Rows.IndexOf(m_GridParent.CurrentRow);
            int index = m_GridParent.SelectedRows[0].Index;
            string filename = (string)m_GridParent.Rows[index].Cells["Filename"].Value;

            // Remove the file from the "Add Sound" drop-down menu
            ((Editor)m_EditorParent).AddSoundDropDown.Items.Remove(filename);

            // Remove the file from the library
            m_FileList.Remove(GetFileByFilename(filename));

            // Remove the row from display in the soundbank
            //m_GridParent.Rows.Remove(m_GridParent.CurrentRow);
            m_GridParent.Rows.Remove(m_GridParent.SelectedRows[0]);
            m_Size--;


            // Delete the sound from any events in the tree -------------------------------------------------
            int x = 0;
            // the number of events in the tree
            int numEvents = ((Editor)m_EditorParent).EventTree.Nodes.Count;

            // for each parent Event
            while (x < numEvents)
            {
                // the number of sounds in each event
                int numSounds = ((Editor)m_EditorParent).EventTree.Nodes[x].Nodes.Count;
                int y = 0;
                int counter = 0;

                int indexOffset = 0;

                // for each sound in the event
                while (counter < numSounds)
                {
                    // check if it's text is the same as our filename
                    if (((Editor)m_EditorParent).EventTree.Nodes[x].Nodes[y].Text.CompareTo(filename) == 0)
                    {
                        // Remove from the list
                        ((Editor)m_EditorParent).EventTree.Nodes[x].Nodes[y].Remove();

                        // Since we removed a node, need to decrement the node positions
                        --y;
                    }

                    if (filename == ((Editor)m_EditorParent).GetEventTree().GetEventSound(((Editor)m_EditorParent).EventTree.Nodes[x].Text, counter - indexOffset).GetName())
                    {
                        ((Editor)m_EditorParent).GetEventTree().RemoveSound(((Editor)m_EditorParent).EventTree.Nodes[x].Text, counter - indexOffset);
                        ++indexOffset;
                    }

                    ++y;
                    ++counter;
                }
                ++x;
            }

            // End tree-sound deletion --------------------------------------------------------------------------
            
        }

        public int GetSize()
        {
            return m_Size;
        }

        // Search for a SoundFile by its filename, and return it if found
        public SoundFile GetFileByFilename(string filename)
        {
            for (int i = 0; i < m_Size; ++i)
            {
                SoundFile temp = (SoundFile)m_FileList[i];

                if (filename == temp.GetFileName())
                {
                    return (SoundFile)m_FileList[i];
                }
            }

            return null;
        }
    }
}
